home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / texte / qed / src / window.c < prev    next >
C/C++ Source or Header  |  1998-08-26  |  24KB  |  1,168 lines

  1. #include "global.h"
  2. #include "av.h"
  3. #include "clipbrd.h"
  4. #include "comm.h"
  5. #include "event.h"
  6. #include "icon.h"
  7. #include "makro.h"
  8. #include "menu.h"
  9. #include "options.h"
  10. #include "rsc.h"
  11. #include "set.h"
  12. #include "winlist.h"
  13. #include "window.h"
  14.  
  15. #ifndef WM_SHADED
  16. #define WM_SHADED                0x5758
  17. #define WM_UNSHADED            0x5759
  18. #define WF_SHADE                0x575D
  19. #endif
  20.  
  21. #ifndef WF_M_BACKDROP
  22. #define WF_M_BACKDROP        100
  23. #endif
  24.  
  25. /*
  26.  * exportierte Variablen
  27.  */
  28.  
  29. WINDOWP     sel_window;        /* Zeiger auf selektiertes Fenster */
  30. SET        sel_objs;        /* Menge selektierter Objekte */
  31. bool        all_iconified;
  32.  
  33.  
  34. #define MIN_WIDTH        (8 * gl_wchar)            /* Kleinste Breite */
  35. #define MIN_HEIGHT     (8 * gl_hchar)            /* Kleinste Höhe */
  36.  
  37. #define WORK_MOVED    0x01                /* Für Verschieben und Vergrößern */
  38. #define WORK_SIZED    0x02
  39.  
  40.  
  41. /*
  42.  * lokale Variablen
  43. */
  44. static GRECT    border;
  45. static int        top_handle;
  46.  
  47. /*
  48.  * Anzahl der offenen Fenster einer Klasse ermitteln.
  49. */
  50. int num_openwin(int class)
  51. {
  52.     WINDOWP    p = used_list;
  53.     int        anz = 0;
  54.  
  55.     while (p)
  56.     {
  57.         if ((p->flags & WI_OPEN) && ((p->class == class) || (class == CLASS_ALL)))
  58.             anz++;
  59.         p = p->next;
  60.     }
  61.     return anz;
  62. }
  63.  
  64. /*
  65.  * Listenelement zu AES-Fensterhandle suchen.
  66. */
  67. WINDOWP get_window(int handle)
  68. {
  69.     WINDOWP    p = used_list;
  70.  
  71.     while (p)
  72.     {
  73.         if (p->handle == handle)
  74.             return p;
  75.         p = p->next;
  76.     }
  77.     return NULL;
  78. }
  79.  
  80. /*
  81.  * Funktion auf bestimmte Fensterklasse anwenden.
  82. */
  83. void do_all_window(int class, WIN_DOFUNC func)
  84. {
  85.     WINDOWP    p = used_list;
  86.  
  87.     while (p)
  88.     {
  89.         if ((p->handle != UNUSED) && ((p->class == class) || (class == CLASS_ALL)))
  90.             (*func)(p);
  91.         p = p->next;
  92.     }
  93. }
  94.  
  95. /*
  96.  * Erstes Fenster aus der Liste.
  97. */
  98. WINDOWP winlist_top(void)            /* ehemals top() */
  99. {
  100.     if (used_list && used_list->handle != UNUSED)
  101.         return used_list;
  102.     else
  103.         return NULL;
  104. }
  105.  
  106. /*
  107.  * Top-Fenster vom AES.
  108. */
  109. void get_realtop(void)
  110. {
  111.     int    d;
  112.  
  113.     wind_get(0, WF_TOP, &top_handle, &d, &d, &d);
  114. }
  115.  
  116. /*
  117.  * Liefert Listenelement, das gleichzeitig oberstes AES-Fenster ist.
  118. */
  119. WINDOWP real_top(void)
  120. {
  121.     WINDOWP    w;
  122.  
  123.     w = winlist_top();
  124.     if (w == NULL)
  125.         return NULL;
  126.     get_realtop();
  127.     return ((w->handle == top_handle) ? w : NULL);
  128. }
  129.  
  130. /*
  131.  * Fenster auf Bytegrenze einrasten.
  132. */
  133. static void snap_window(WINDOWP w, GRECT *new, int mode)
  134. {
  135.     if (mode & WORK_SIZED)
  136.     {
  137.         new->g_w = new->g_w-(new->g_w % w->xfac);
  138.         new->g_h = new->g_h-(new->g_h % w->yfac);
  139.     }
  140.  
  141.     if (w->snap != NULL)
  142.         (*w->snap)(w, new, mode);
  143. }
  144.  
  145. /*
  146.  * Fenster an Bildschirm anpassen.
  147. */
  148. static void get_work(WINDOWP w, GRECT *new, int mode)
  149. {
  150.     if (mode & WORK_SIZED)
  151.     {
  152.         if (new->g_w < MIN_WIDTH)
  153.             new->g_w = MIN_WIDTH;
  154.         if (new->g_h < MIN_HEIGHT)
  155.             new->g_h = MIN_HEIGHT;
  156.     }
  157.  
  158.     wind_calc_grect(WC_WORK, w->kind, new, new);
  159.     snap_window(w, new, mode);
  160.  
  161.     /* work und w_* (und doc) anpassen */
  162.     w->work.g_x = new->g_x;
  163.     w->work.g_y = new->g_y;
  164.     if (mode & WORK_SIZED)
  165.     {
  166.         long max_doc;
  167.  
  168.         w->work.g_w = new->g_w;
  169.         w->w_width  = w->work.g_w / w->xfac;
  170.         max_doc = w->doc.w - w->w_width;
  171.         if (max_doc < 0)
  172.             max_doc = 0;
  173.         if (w->doc.x > max_doc)                        /* Jenseits rechter Bereich */
  174.             w->doc.x = max_doc;
  175.  
  176.         w->work.g_h = new->g_h;
  177.         w->w_height  = w->work.g_h / w->yfac;
  178.         max_doc = w->doc.h - w->w_height;
  179.         if (max_doc < 0)
  180.             max_doc = 0;
  181.         if (w->doc.y > max_doc)                        /* Jenseits unterer Bereich */
  182.             w->doc.y = max_doc;
  183.     }
  184.  
  185.     if (w->flags & WI_OPEN)
  186.     {
  187.         wind_calc_grect(WC_BORDER, w->kind,    new, new);
  188.         wind_set_grect(w->handle, WF_CURRXYWH, new);
  189.     }
  190.  
  191.     if (mode & WORK_SIZED)
  192.         set_sliders(w, HORIZONTAL+VERTICAL, SLPOS+SLSIZE);
  193. }
  194.  
  195. /*
  196.  * Rechteckliste
  197. */
  198. bool rc_first(int wh, GRECT *b, GRECT *r)
  199. {
  200.     border = *b;
  201.     if (!rc_intersect(&gl_desk, &border))                    /* mit Bildschirm schneiden */
  202.         return FALSE;
  203.     wind_get_grect(wh, WF_FIRSTXYWH, r);
  204.     while (r->g_w && r->g_h)
  205.     {
  206.         if (rc_intersect(&border, r))                        /* Schneide Rechtecke */
  207.             return TRUE;
  208.         wind_get_grect(wh, WF_NEXTXYWH, r);
  209.     }
  210.     return FALSE;
  211. }
  212.  
  213. bool rc_next(int wh, GRECT *r)
  214. {
  215.     wind_get_grect(wh, WF_NEXTXYWH, r);
  216.     while (r->g_w && r->g_h)
  217.     {
  218.         if (rc_intersect(&border, r))
  219.             return TRUE;
  220.         wind_get_grect(wh, WF_NEXTXYWH, r);
  221.     }
  222.     return FALSE;
  223. }
  224.  
  225. /*
  226.  * Festerinhalt zeichnen
  227. */
  228. void clr_area (GRECT *area)
  229. {
  230.     int    xy[4];
  231.  
  232.     grect_to_array(area, xy);                                /* Bereich setzen */
  233.     if (fill_color!=WHITE)
  234.     {
  235.         vsf_color(vdi_handle,WHITE);
  236.         fill_color = WHITE;
  237.     }
  238.     vr_recfl(vdi_handle, xy);                                /* Bereich löschen */
  239. }
  240.  
  241. bool free_for_draw(WINDOWP w)
  242. {
  243.     GRECT draw;
  244.  
  245.     if (rc_first(w->handle, &w->work, &draw))
  246.     {
  247.         if (w->work.g_w == draw.g_w && w->work.g_h == draw.g_h)
  248.             return TRUE;
  249.     }
  250.     return FALSE;
  251. }
  252.  
  253. void redraw_window(WINDOWP w, GRECT *area)
  254. {
  255.     GRECT    r1;
  256.  
  257.     if (w == NULL)
  258.         return;
  259.  
  260.     wind_update(BEG_UPDATE);
  261.     
  262.     if (w->flags & WI_NOTDRAWED)
  263.         w->flags &= (~WI_NOTDRAWED);
  264.  
  265.     else if ((w->flags & WI_OPEN) || (w->flags & WI_ICONIFIED))
  266.     {
  267.         if (w->flags & WI_ICONIFIED)
  268.         {
  269.             /*
  270.              * Icon-Position wieder eintragen, da alle Fenster den gleichen
  271.              * Objektbaum benutzen!!!
  272.              */
  273.             winicon[0].ob_x = w->icon_x;
  274.             winicon[0].ob_y = w->icon_y;
  275.         }
  276.         if (rc_first(w->handle, area, &r1))
  277.         {
  278.             hide_mouse();
  279.             do
  280.             {
  281.                 if (w->flags & WI_ICONIFIED)
  282.                 {
  283.                     if (rc_intersect (area, &r1))
  284.                         objc_draw(winicon, ROOT, MAX_DEPTH, r1.g_x, r1.g_y, r1.g_w, r1.g_h);
  285.                 }
  286.                 else
  287.                 {
  288.                     if (w->draw!=NULL)                    /* Zeichenroutine ausführen */
  289.                         (*w->draw)(w, &r1);
  290.                 }
  291.             }
  292.             while (rc_next(w->handle, &r1));
  293.             show_mouse();
  294.         }
  295.     }
  296.     wind_update(END_UPDATE);
  297. }
  298.  
  299. /*
  300.  * Setzt die Größe.
  301. */
  302. void size_window(WINDOWP w, GRECT *new, bool border)
  303. {
  304.     GRECT r;
  305.  
  306.     if (w != NULL)
  307.     {
  308.         if (!border)
  309.             wind_calc_grect(WC_BORDER, w->kind, (GRECT*)new, &r);
  310.         else
  311.             r = *new;
  312.         if (w->kind & SIZER)
  313.         {
  314.             get_work(w, &r, WORK_SIZED);
  315.             w->flags &= ~WI_FULLED;
  316.             if (w->flags & WI_REDRAW)
  317.                 redraw_window(w, &w->work);
  318.         }
  319.         else
  320.             move_window(w, &r);
  321.     }
  322. }
  323.  
  324. /*
  325.  * Full/Prev Größe einstellen.
  326. */
  327. void full_window(WINDOWP w)
  328. {
  329.     GRECT    new;
  330.  
  331.     if (w != NULL && w->kind & FULLER)
  332.     {
  333.         if (w->flags & WI_FULLED)                    /* Mache Fenster klein */
  334.             wind_get_grect(w->handle, WF_PREVXYWH, &new);
  335.         else                                                /* Mache Fenster groß */
  336.             wind_get_grect(w->handle, WF_FULLXYWH, &new);
  337.         get_work(w, &new, WORK_MOVED|WORK_SIZED);
  338.         w->flags ^= WI_FULLED;
  339.     }
  340. }
  341.  
  342. /*
  343.  * Iconify.
  344. */
  345. void iconify_window(WINDOWP w, GRECT *new)
  346. {
  347.     unclick_window ();            /* Deselektieren */
  348.  
  349.     if ((w->flags & WI_OPEN) && !(w->flags & WI_ICONIFIED))
  350.     {
  351.         GRECT    r;
  352.  
  353.         if (w->iconify != NULL)
  354.             (*w->iconify)(w);
  355.  
  356.         /* alte Größe merken */
  357.         wind_get_grect(w->handle, WF_CURRXYWH, &w->old_size);
  358.         wind_set_grect(w->handle, WF_ICONIFY, (GRECT*)new);
  359.  
  360.         wind_get_grect(w->handle, WF_WORKXYWH, &r);
  361.         winicon[0].ob_x = r.g_x;
  362.         winicon[0].ob_y = r.g_y;
  363.         winicon[0].ob_width = r.g_w;
  364.         winicon[0].ob_height = r.g_h;
  365.         winicon[1].ob_x = (r.g_w - winicon[1].ob_width) / 2;
  366.         winicon[1].ob_y = (r.g_h - winicon[1].ob_height) / 2;
  367.         w->icon_x = r.g_x;
  368.         w->icon_y = r.g_y;
  369.  
  370.         w->flags |= WI_ICONIFIED;
  371.         w->flags &= ~WI_OPEN;
  372.         
  373.         /*
  374.          * Nur nach hinten, wenn noch min. ein Fenster offen ist, da sonst die
  375.          * Applikation wechselt!
  376.         */
  377.         if (num_openwin(CLASS_ALL) > 0)
  378.             bottom_window(w, WM_BOTTOMED);
  379.     }
  380. }
  381.  
  382. void uniconify_window(WINDOWP w, GRECT *new)
  383. {
  384.     GRECT    r;
  385.  
  386.     if (w != NULL && (w->flags & WI_ICONIFIED))
  387.     {
  388.         if (w->uniconify != NULL)
  389.             (*w->uniconify)(w);
  390.  
  391.         wind_calc_grect(WC_BORDER, w->kind, &w->work, &r);
  392.  
  393.         /* Wurde Font gewechselt während Fenster iconifiziert? */
  394.         if (w->old_size.g_w != r.g_w)
  395.             new = &r;
  396.  
  397.         if (new == NULL)
  398.             wind_set_grect(w->handle, WF_UNICONIFY, &w->old_size);
  399.         else
  400.             wind_set_grect(w->handle, WF_UNICONIFY, (GRECT*)new);
  401.  
  402.         w->flags &= ~WI_ICONIFIED;
  403.         w->flags |= WI_OPEN;
  404.         top_window(w);
  405.     }
  406. }
  407.  
  408. void    all_iconify(WINDOWP w, GRECT *new)
  409. {
  410.     WINDOWP    p;
  411.  
  412.     if (makro_rec)
  413.     {
  414.         Bconout(2, 7);
  415.         return;
  416.     }
  417.  
  418.     /* Zunächst alle Fenster bis auf das angeklickte schließen */
  419.     p = used_list;
  420.     while (p)
  421.     {
  422.         if (p != w)
  423.         {
  424.             wind_close(p->handle);
  425.             if (p->flags & WI_ICONIFIED)
  426.                 uniconify_window(p, NULL);
  427.         }
  428.         p = p->next;
  429.     }
  430.  
  431.     /* und angeklicktes wird zum Icon */
  432.     set_wtitle(w, " qed ");
  433.     iconify_window(w, new);
  434.     disable_menu();
  435.     all_iconified = TRUE;
  436. }
  437.  
  438. void all_uniconify(WINDOWP w, GRECT *new)
  439. {
  440.     GRECT        r;
  441.     WINDOWP    p;
  442.     
  443.     if (all_iconified)
  444.     {
  445.         p = used_list;
  446.         while (p)
  447.         {
  448.             if (p->flags & WI_ICONIFIED)
  449.                 uniconify_window(p, new);
  450.             else
  451.             {
  452.                 wind_calc_grect(WC_BORDER, p->kind, &p->work, &r);
  453.                 wind_open_grect(p->handle, &r);
  454.             }
  455.             p = p->next;
  456.         }
  457.  
  458. #if 0
  459.         /* damit wieder das richtige oben ist */
  460.         top_window(w);
  461. #endif
  462.  
  463.         enable_menu();
  464.         all_iconified = FALSE;
  465.     }
  466. }
  467.  
  468. /*
  469.  * Setzt die Position.
  470. */
  471. void move_window(WINDOWP w, GRECT *new)
  472. {
  473.     if (w != NULL)
  474.     {
  475.         if (w->flags & WI_ICONIFIED)
  476.         {
  477.             int    x, y, d;
  478.  
  479.             /* Icon anpassen */
  480.             wind_set_grect(w->handle, WF_CURRXYWH, (GRECT*)new);
  481.             wind_get(w->handle, WF_WORKXYWH, &x, &y, &d, &d);
  482.             winicon[0].ob_x = x;
  483.             winicon[0].ob_y = y;
  484.             w->icon_x = x;
  485.             w->icon_y = y;
  486.         }
  487.         else if (w->kind & MOVER)
  488.         {
  489.             GRECT r;
  490.  
  491.             r = *new;
  492.             get_work(w, &r, WORK_MOVED);
  493.             w->flags &= ~WI_FULLED;
  494.         }
  495.     }
  496. }
  497.  
  498. /*
  499.  * Fenster von qed wurde aktiv.
  500. */
  501. void ontop_window(WINDOWP w)
  502. {
  503.     if (w != NULL && w->ontop != NULL)
  504.         (*w->ontop)(w);
  505. }
  506.  
  507. /*
  508.  * Fenster von qed wurde inaktiv.
  509. */
  510. void untop_window(WINDOWP w)
  511. {
  512.     if (w != NULL && w->untop != NULL)
  513.         (*w->untop)(w);
  514. }
  515.  
  516. /*
  517.  * Macht Fenster zum Aktiven.
  518. */
  519. void top_window(WINDOWP w)
  520. {
  521.     if (w == NULL || !(w->flags & WI_OPEN) && !(w->flags & WI_ICONIFIED))
  522.         return;
  523.  
  524.     if (w->top != NULL)
  525.         (*w->top)(w);
  526.  
  527.     wind_set(w->handle, WF_TOP, 0, 0, 0, 0);
  528.     top_handle = w->handle;
  529.  
  530.     if (w != sel_window)
  531.         unclick_window();
  532.  
  533.     if (w != used_list)                    /* War nicht top in der Liste */
  534.     {
  535.         clr_undo();
  536.         move_to_top(w);
  537.     }
  538. }
  539.  
  540. /*
  541.  * Nächstes Fenster toppen.
  542. */
  543. void cycle_window(void)
  544. {
  545.     WINDOWP    w, last;
  546.     
  547.     if (used_list && used_list->next)        /* min. 2 Fenster offen */
  548.     {
  549.         w = used_list;
  550.         last = NULL;
  551.         while (w)                                    /* letzten CLASS_EDIT suchen */
  552.         {
  553.             if ((shift_pressed() || (w->class == CLASS_EDIT)) && !(w->flags & WI_ICONIFIED))
  554.                 last = w;
  555.             w = w->next;
  556.         }
  557.         if (last)
  558.             top_window(last);
  559.     }
  560. }
  561.  
  562. /*
  563.  * Stellt Fenster nach hinten.
  564. */
  565. void bottom_window(WINDOWP w, int which)
  566. {
  567.     if (w == NULL || !(w->flags & WI_OPEN) && !(w->flags & WI_ICONIFIED))
  568.         return;
  569.  
  570.     if (w->bottom != NULL)
  571.         (*w->bottom)(w);
  572.  
  573.     if (which == WM_BOTTOMED)                                    /* MTOS, MagiC >= 3 */
  574.         wind_set(w->handle, WF_BOTTOM, 0, 0, 0, 0);
  575.     else                                                                /* Magic 2 */
  576.         wind_set(w->handle, WF_M_BACKDROP, 0, 0, 0, 0);
  577.  
  578.     clr_undo();
  579.     move_to_end(w);
  580.  
  581.     get_realtop();                    /* qed über das neue top-Fenster informieren */
  582.     memset(msgbuff, 0, (int) sizeof(msgbuff));
  583.     msgbuff[0] = WM_TOPPED;
  584.     msgbuff[3] = top_handle;
  585.     send_msg(gl_apid);
  586. }
  587.  
  588. /*
  589.  * Fenster-Shading (Reduktion auf Titel)
  590.  * Winx 2.3, MagiC 5.2, N.AES 1.1.7
  591. */
  592. void shade_window(WINDOWP w, int mode)
  593. {
  594.     if (w == NULL)
  595.         return;
  596.  
  597.     switch (mode)
  598.     {
  599.         case WM_SHADED :
  600.             w->flags |= WI_SHADED;
  601.             break;
  602.             
  603.         case WM_UNSHADED :
  604.             w->flags &= ~WI_SHADED;
  605.             break;
  606.  
  607.         case -1 :
  608.             wind_set(w->handle, WF_SHADE, 0, 0, 0, 0);
  609.             w->flags &= ~WI_SHADED;
  610.             top_window(w);
  611.             break;
  612.     }
  613. }
  614.  
  615. /*
  616.  * Scrollt den Inhalt des Fensters.
  617. */
  618. static void scroll_window(WINDOWP w, int dir, long delta)
  619. {
  620.     MFDB        s, d;
  621.     int        xy[8];
  622.     GRECT        r;
  623.     bool    draw;
  624.  
  625.     draw = FALSE;
  626.     wind_get_grect(w->handle, WF_FIRSTXYWH, &r);
  627.     if (r.g_w != w->work.g_w || r.g_h != w->work.g_h)
  628.         draw = TRUE;
  629.  
  630.     r = w->work;
  631.     if (!rc_intersect(&gl_desk, &r))
  632.         return;
  633.  
  634.     if (dir & HORIZONTAL)
  635.     {
  636.         delta *= w->xfac;
  637.         if (labs(delta) >= r.g_w)
  638.             draw = TRUE;
  639.     }
  640.     else
  641.     {
  642.         delta *= w->yfac;
  643.         if (labs(delta) >= r.g_h)
  644.             draw = TRUE;
  645.     }
  646.  
  647.     if (!draw)
  648.     {
  649.         grect_to_array(&r, xy);                        /* Quelle für vro_cpyfm */
  650.         xy[4] = xy[0];                                    /* Ziel für vro_cpyfm */
  651.         xy[5] = xy[1];
  652.         xy[6] = xy[2];
  653.         xy[7] = xy[3];
  654.  
  655.         if (dir & HORIZONTAL)                        /* Horizontales Scrolling */
  656.         {
  657.             if (delta > 0)                                /* Links Scrolling */
  658.             {
  659.                 xy[0] += (int) delta;
  660.                 xy[6] -= (int) delta;
  661.  
  662.                 r.g_x += r.g_w - (int)delta;    /* Rechter Bereich nicht gescrollt, */
  663.                 r.g_w  = (int)delta;                /* muß neu gezeichnet werden */
  664.             }
  665.             else                                            /* Rechts Scrolling */
  666.             {
  667.                 xy[2] += (int)delta;
  668.                 xy[4] -= (int)delta;
  669.  
  670.                 r.g_w = (int)(-delta);            /* Linken Bereich noch neu zeichnen */
  671.             }
  672.         }
  673.         else                                                /* Vertikales Scrolling */
  674.         {
  675.             if (delta > 0)                                /* Aufwärts Scrolling */
  676.             {
  677.                 xy[1] += (int)delta;                /* Werte für vro_cpyfm */
  678.                 xy[7] -= (int)delta;
  679.  
  680.                 r.g_y += r.g_h - (int)delta;    /* Unterer Bereich nicht gescrollt, */
  681.                 r.g_h  = (int) delta;                /* muß neu gezeichnet werden */
  682.             }
  683.             else                                            /* Abwärts Scrolling */
  684.             {
  685.                 xy[3] += (int)delta;                /* Werte für vro_cpyfm */
  686.                 xy[5] -= (int)delta;
  687.  
  688.                 r.g_h = (int)(-delta);            /* Oberen Bereich noch neu zeichnen */
  689.             }
  690.         }
  691.         s.fd_addr = d.fd_addr = NULL;                /* Erzwinge Bildschirmadresse */
  692.         set_clip(TRUE, &w->work);
  693.         hide_mouse();
  694.         vro_cpyfm(vdi_handle, S_ONLY, xy, &s, &d);
  695.         show_mouse();
  696.         redraw_window(w, &r);
  697.     }
  698.     else
  699.         redraw_window(w, &r);                        /* Fenster zeichnen */
  700. }
  701.  
  702. void scroll_vertical(GRECT *area, int delta)
  703. {
  704.     MFDB    s, d;
  705.     int    xy[8];
  706.  
  707.     grect_to_array(area, xy);
  708.     xy[4] = xy[0];
  709.     xy[5] = xy[1]-delta;
  710.     xy[6] = xy[2];
  711.     xy[7] = xy[3]-delta;
  712.  
  713.     s.fd_addr = d.fd_addr = NULL;                            /* Erzwinge Bildschirmadresse */
  714.     vro_cpyfm (vdi_handle, S_ONLY, xy, &s, &d);        /* Eigentliches Scrolling */
  715. }
  716.  
  717. /*
  718.  * Auswertung der Scroll-Pfeile.
  719. */
  720. static void do_arrow(WINDOWP w, int dir, long delta)
  721. {
  722.     if (delta)
  723.     {
  724.         if (dir == HORIZONTAL)                        /* Horizontale Pfeile und Schieber */
  725.             w->doc.x += delta;                        /* Neue Position */
  726.         else                                                /* Vertikale Pfeile und Schieber */
  727.             w->doc.y += delta;                        /* Neue Position */
  728.         if (w->flags & WI_OPEN)
  729.         {
  730.             set_sliders(w, dir, SLPOS);            /* Schieber setzen */
  731.             scroll_window(w, dir, delta);
  732.         }
  733.     }
  734. }
  735.  
  736. void arrow_window (WINDOWP w, int arrow, long amount)
  737. {
  738.     int     ww, wh, dir;
  739.     long     oldpos, newpos, max_slide;
  740.  
  741.     if (w != NULL)
  742.     {
  743.         ww = w->w_width;                                 /* Breite in Zeichen */
  744.         wh = w->w_height;                                /* Höhe in Zeichen */
  745.  
  746.         if (arrow <= WA_DNLINE)
  747.         {
  748.             oldpos = newpos = w->doc.y;
  749.             dir     = VERTICAL;
  750.             max_slide = w->doc.h - wh;                /* Maximale Position */
  751.         }
  752.         else
  753.         {
  754.             oldpos = newpos = w->doc.x;
  755.             dir     = HORIZONTAL;
  756.             max_slide = w->doc.w - ww;                /* Maximale Position */
  757.         }
  758.         switch (arrow)
  759.         {
  760.             case WA_UPPAGE :
  761.                 newpos -= wh * amount;
  762.                 break;
  763.             case WA_DNPAGE :
  764.                 newpos += wh * amount;
  765.                 break;
  766.             case WA_UPLINE :
  767.                 newpos -= amount;
  768.                 break;
  769.             case WA_DNLINE :
  770.                 newpos += amount;
  771.                 break;
  772.             case WA_LFPAGE :
  773.                 newpos -= ww * amount;
  774.                 break;
  775.             case WA_RTPAGE :
  776.                 newpos += ww * amount;
  777.                 break;
  778.             case WA_LFLINE :
  779.                 newpos -= amount;
  780.                 break;
  781.             case WA_RTLINE :
  782.                 newpos += amount;
  783.                 break;
  784.         }
  785.  
  786.         if (newpos > max_slide)
  787.             newpos = max_slide;                            /* Jenseits des Randes */
  788.         if (newpos < 0)
  789.             newpos = 0;                                         /* Jenseits des Randes */
  790.         do_arrow(w, dir, newpos-oldpos);
  791.     }
  792. }
  793.  
  794. /*
  795.  * Auswertung des horizontalen Sliders.
  796. */
  797. void h_slider(WINDOWP w, int new_value)
  798. {
  799.     long    oldpos, newpos, max_slide;
  800.  
  801.     if (w != NULL)
  802.     {
  803.         max_slide = w->doc.w - w->w_width;        /* Maximale Position */
  804.         oldpos = w->doc.x;
  805.         newpos = (long)new_value * max_slide;
  806.         newpos = (newpos+500) / 1000;                /* Teilen + Runden */
  807.  
  808.         if (newpos > max_slide)
  809.             newpos = max_slide;                        /* Jenseits des Randes */
  810.         if (newpos < 0)
  811.             newpos = 0;                                    /* Jenseits des Randes */
  812.         do_arrow(w, HORIZONTAL, newpos-oldpos);
  813.     }
  814. }
  815.  
  816. /*
  817.  * Auswertung des vertikalen Sliders.
  818. */
  819. void v_slider(WINDOWP w, int new_value)
  820. {
  821.     long    oldpos, newpos, max_slide;
  822.  
  823.     if (w != NULL)
  824.     {
  825.         max_slide = w->doc.h - w->w_height;        /* Maximale Position */
  826.         oldpos = w->doc.y;
  827.         newpos = (long)new_value * max_slide;
  828.         newpos = (newpos+500) / 1000;                /* Teilen + Runden */
  829.  
  830.         if (newpos > max_slide)
  831.             newpos = max_slide;                        /* Jenseits des Randes */
  832.         if (newpos < 0)
  833.             newpos = 0;                                    /* Jenseits des Randes */
  834.         do_arrow(w, VERTICAL, newpos-oldpos);
  835.     }
  836. }
  837.  
  838. /*
  839.  * Slieder einstellen.
  840. */
  841. void set_sliders(WINDOWP w, int which, int mode)
  842. {
  843.     int    d;
  844.     int    size, newval, oldval;
  845.     long    max_doc;
  846.  
  847.     if (w->flags & WI_OPEN)
  848.     {
  849.         if ((which & HORIZONTAL) && (w->kind & HSLIDE))
  850.         {
  851.             size = w->w_width;
  852.             max_doc = w->doc.w - size;
  853.  
  854.             if (mode & SLPOS)
  855.             {
  856.                 if (max_doc <= 0)            /* Fenster zu groß oder passend */
  857.                     newval = 0;
  858.                 else
  859.                     newval = (int)((1000L * w->doc.x) / max_doc);
  860.  
  861.                 wind_get (w->handle, WF_HSLIDE, &oldval, &d, &d, &d);
  862.                 if (newval != oldval)
  863.                     wind_set(w->handle, WF_HSLIDE, newval, 0, 0, 0);
  864.             }
  865.             if (mode & SLSIZE)
  866.             {
  867.                 if (w->doc.w <= size)    /* Fenster zu groß oder passend */
  868.                     newval = 1000;
  869.                 else
  870.                     newval = (int)((1000L * size) / w->doc.w);
  871.  
  872.                 wind_get(w->handle, WF_HSLSIZE, &oldval, &d, &d, &d);
  873.                 if (newval != oldval)
  874.                     wind_set(w->handle, WF_HSLSIZE, newval, 0, 0, 0);
  875.             }
  876.         }
  877.         if ((which & VERTICAL) && (w->kind & VSLIDE))
  878.         {
  879.             size = w->w_height;
  880.             max_doc = w->doc.h - size;
  881.  
  882.             if (mode & SLPOS)
  883.             {
  884.                 if (max_doc <= 0)            /* Fenster zu groß oder passend */
  885.                     newval = 0;
  886.                 else
  887.                     newval = (int)((1000L * w->doc.y) / max_doc);
  888.                 wind_get(w->handle, WF_VSLIDE, &oldval, &d, &d, &d);
  889.                 if (newval != oldval)
  890.                     wind_set(w->handle, WF_VSLIDE, newval, 0, 0, 0);
  891.             }
  892.             if (mode & SLSIZE)
  893.             {
  894.                 if (w->doc.h <= size)    /* Fenster zu groß oder passend */
  895.                     newval = 1000;
  896.                 else
  897.                     newval = (int)((1000L * size) / w->doc.h);
  898.                 wind_get (w->handle, WF_VSLSIZE, &oldval, &d, &d, &d);
  899.                 if (newval != oldval)
  900.                     wind_set(w->handle, WF_VSLSIZE, newval, 0, 0, 0);
  901.             }
  902.         }
  903.     }
  904. }
  905.  
  906. /*
  907.  * Fenstertitel setzen.
  908. */
  909. void set_wtitle(WINDOWP w, char *filename)
  910. {
  911.     if (w->flags & WI_CHANGED)
  912.         sprintf(w->title, " *%s ", filename);
  913.     else
  914.         sprintf(w->title, " %s ", filename);
  915.  
  916.     if ((w->flags & WI_OPEN) && (w->kind & NAME))
  917.         wind_set_str(w->handle, WF_NAME, w->title);
  918. }
  919.  
  920. /*
  921.  * Fensterinfozeile setzen.
  922. */
  923. void set_winfo(WINDOWP w, char *info)
  924. {
  925.     strncpy(w->info, info, WINSTRLEN);
  926.     w->info[WINSTRLEN] = EOS;
  927.  
  928.     if ((w->flags & WI_OPEN) && (w->kind & INFO))
  929.         wind_set_str(w->handle, WF_INFO, w->info);
  930. }
  931.  
  932. /*
  933.  * '*' im Titel an/abschalten.
  934. */
  935. void change_window(WINDOWP w, char *filename, bool changed)
  936. {
  937.     bool    old;
  938.     
  939.     if (w->flags & WI_CHANGED)
  940.         old = TRUE;
  941.     else
  942.         old = FALSE;
  943.     if (old != changed)
  944.     {
  945.         w->flags ^= WI_CHANGED;
  946.         set_wtitle(w, filename);
  947.     }
  948. }
  949.  
  950. /*
  951.  * Neues Fenster anfordern.
  952. */
  953. WINDOWP create_window(int kind, int class, WIN_CRTFUNC crt)
  954. {
  955.     WINDOWP    w;
  956.     int        wh;
  957.  
  958.     w = get_new_window(class);
  959.     if (w)
  960.     {
  961.         wh = wind_create_grect(kind, &gl_desk);
  962.         if (wh < 0)
  963.             return NULL;
  964.         w->handle = wh;
  965.         w->kind = kind;
  966.  
  967.         if (crt != NULL)
  968.             (*crt)(w);
  969.  
  970.         if (class != CLASS_ICON)
  971.             size_window(w, &w->work, FALSE);
  972.     }
  973.     return w;
  974. }
  975.  
  976. /*
  977.  * Fenster öffnen.
  978. */
  979. bool open_window(WINDOWP w)
  980. {
  981.     GRECT    r;
  982.  
  983.     if (w && !(w->flags & WI_OPEN))
  984.     {
  985.  
  986.         clr_undo();
  987.         unclick_window();
  988.         w->flags |= WI_OPEN;
  989.         w->flags &= ~WI_FULLED;                    /* Fenster hat nicht volle Größe */
  990.  
  991.         wind_calc_grect(WC_BORDER, w->kind, &w->work, &r);
  992.  
  993.         if (w->kind & NAME)                        /* Name setzen */
  994.             wind_set_str(w->handle, WF_NAME, w->title);
  995.  
  996.         if (w->kind & INFO)                        /* Infozeile setzen */
  997.             wind_set_str(w->handle, WF_INFO, w->info);
  998.  
  999.         set_sliders(w, HORIZONTAL+VERTICAL, SLPOS+SLSIZE);
  1000.  
  1001.         wind_open_grect(w->handle, &r);
  1002.         top_handle = w->handle;
  1003.         move_to_top(w);
  1004.         redraw_window(w, &w->work);
  1005.         w->flags |= WI_NOTDRAWED;
  1006.         send_avwinopen(w->handle);
  1007.         return TRUE;
  1008.     }
  1009.     return TRUE;
  1010. }
  1011.  
  1012. /*
  1013.  * Fenster schließen.
  1014. */
  1015. void close_window(WINDOWP w)
  1016. {
  1017.     if (w != NULL)
  1018.     {
  1019.         unclick_window();                                                        /* Deselektieren */
  1020.         if ((w->flags & WI_OPEN) || (w->flags & WI_ICONIFIED))    /* Fenster offen? */
  1021.         {
  1022.             wake_mouse();
  1023.             if (w->close != NULL)
  1024.                 (*w->close)(w);
  1025.  
  1026.             wind_close(w->handle);
  1027.             wind_delete(w->handle);
  1028.  
  1029.             send_avwinclose(w->handle);
  1030.             w->flags &= ~WI_OPEN;
  1031.             get_realtop();
  1032.             clr_undo();
  1033.         }
  1034.         free_window(w);
  1035.     }
  1036. }
  1037.  
  1038. /*
  1039.  * Neuen Font einstellen.
  1040. */
  1041. void do_font_change(WINDOWP w)
  1042. {
  1043.     GRECT    r;
  1044.  
  1045.     if (w->flags & WI_FONTSIZE)
  1046.     {
  1047.         w->xfac = font_wcell;
  1048.         w->yfac = font_hcell;
  1049.  
  1050.         r.g_x = w->work.g_x;
  1051.         r.g_y = w->work.g_y;
  1052.         r.g_w = w->work.g_w;
  1053.         r.g_h = font_hcell * w->w_height;
  1054.         if ((r.g_h + r.g_y) > gl_desk.g_h)
  1055.             r.g_h = gl_desk.g_h - r.g_y;
  1056.         size_window(w, &r, FALSE);
  1057.         redraw_window(w, &w->work);
  1058.     }
  1059. }
  1060.  
  1061. /*
  1062.  * Auswertung von Mausklicks.
  1063. */
  1064. void click_window(WINDOWP w, int m_x, int m_y, int bstate, int kstate, int breturn)
  1065. {
  1066.     if (w != NULL && !(w->flags & WI_ICONIFIED))
  1067.     {
  1068.         if (w->click!=NULL)
  1069.             (*w->click)(w, m_x, m_y, bstate, kstate, breturn);
  1070.         else
  1071.             unclick_window();
  1072.     }
  1073. }
  1074.  
  1075. /*
  1076.  * Deselektieren eine Fensters.
  1077. */
  1078. void unclick_window (void)
  1079. {
  1080.     if (sel_window != NULL && sel_window->unclick != NULL)
  1081.         (*sel_window->unclick) (sel_window);
  1082.     sel_window = NULL;
  1083.     setclr(sel_objs);
  1084. }
  1085.  
  1086. /*
  1087.  * Auswertung von Tastaturdaten.
  1088. */
  1089. bool key_window(WINDOWP w, int kstate, int kreturn)
  1090. {
  1091.     if (w->key != NULL && !(w->flags & WI_ICONIFIED) && !(w->flags & WI_SHADED))
  1092.         return ((*w->key)(w, kstate, kreturn));
  1093.     return (FALSE);
  1094. }
  1095.  
  1096. /*
  1097.  * Fenster anordnen. Funktion kommt aus den 7Up 2.3 Quellen.
  1098. */
  1099. void arrange_window(int mode)
  1100. {
  1101.     int        count, xstep, ystep, k, diff;
  1102.     GRECT        rect;
  1103.     WINDOWP    p = used_list;
  1104.  
  1105.     count = num_openwin(CLASS_EDIT);
  1106.     if (count > 1)
  1107.     {
  1108.         xstep = gl_desk.g_w / count;
  1109.         diff = (count - 1) * xstep + MIN_WIDTH - gl_desk.g_w;
  1110.         if( diff > 0)
  1111.             xstep -= diff / count;
  1112.  
  1113.         ystep = gl_desk.g_h / count;
  1114.         diff = (count - 1) * ystep + MIN_HEIGHT - gl_desk.g_h;
  1115.         if(diff > 0)
  1116.             ystep -= diff / count;
  1117.  
  1118.         k = 0;
  1119.         while (p)
  1120.         {
  1121.             if ((p->flags & WI_OPEN) && (p->kind & SIZER) && (p->flags & WI_TEXT))
  1122.             {
  1123.                 switch(mode)
  1124.                 {
  1125.                     case MHINTER:
  1126.                         rect.g_x = k * gl_desk.g_y + gl_desk.g_x;
  1127.                         rect.g_y = k * gl_desk.g_y + gl_desk.g_y;
  1128.                         rect.g_w = gl_desk.g_w - (count - 1) * gl_desk.g_y;
  1129.                         rect.g_h = gl_desk.g_h - (count - 1) * gl_desk.g_y;
  1130.                         break;
  1131.                     case MNEBEN:
  1132.                         rect.g_x = k * xstep + gl_desk.g_x;
  1133.                         rect.g_y = gl_desk.g_y;
  1134.                         rect.g_w = xstep;
  1135.                         rect.g_h = gl_desk.g_h;
  1136.                         break;
  1137.                     case MUNTER:
  1138.                         rect.g_x = gl_desk.g_x;
  1139.                         rect.g_y = k * ystep + gl_desk.g_y;
  1140.                         rect.g_w = gl_desk.g_w;
  1141.                         rect.g_h = ystep;
  1142.                         break;
  1143.                 }
  1144.                 size_window(p, &rect, TRUE);
  1145.                 k++;
  1146.             }
  1147.             p = p->next;
  1148.         }
  1149.     }
  1150. }
  1151.  
  1152. /*
  1153.  * Modul-Init
  1154. */
  1155. void init_window(void)
  1156. {
  1157.     init_winlist();
  1158.      sel_window = NULL;
  1159.     setclr(sel_objs);
  1160.     top_handle = -1;
  1161.     all_iconified = FALSE;
  1162. }
  1163.  
  1164. void term_window(void)
  1165. {
  1166.     term_winlist();
  1167. }
  1168.